package com.netrust.cmsx.core.persist;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.Table;

import org.springframework.data.util.ReflectionUtils;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.reflect.Reflection;
import com.netrust.cmsx.utils.relfect.Reflections;


@Repository
@Transactional(readOnly = true)
public class TreeDaoImpl<T,ID extends Serializable>  extends BaseDaoImpl<T, ID> implements TreeDao<T,ID> {
	private final Class<T> domainClass;

	public TreeDaoImpl(Class<T> domainClass, EntityManager entityManager) {
        super(domainClass, entityManager);
        this.domainClass = domainClass;
    }

	
	@SuppressWarnings("unchecked")
	public List<T> findChildByParent(T entity) {
		String entityname = getTableName(domainClass); 
		String id = null;
		if (entity != null){
			id = (String)Reflections.getFieldValue(entity, "id");
		}
		
		boolean flag=true;
		try {
			entity.getClass().getDeclaredField("delFlag");
		} catch (Exception e) {
			flag=false;
		}
		
		String sql="select * from "+entityname+" o where o.parent_id = "+id;
		if (flag) {
			sql=sql+" and del_Flag = 0";
		}
		
		Query query=super.em.createNativeQuery(sql, entity.getClass());
		
		return query.getResultList();
	}

	/**
	 * 
	 	BEGIN      
		DECLARE str varchar(1000);     
		DECLARE cid varchar(100); 
	     
		SET str = '$';      
		SET cid = rootId;      
			
		IF tableName = 'sys_dict' THEN    
						WHILE cid is not null DO      
										SET str = concat(str, ',', cid);      
										SELECT group_concat(id) INTO cid FROM sys_dict where FIND_IN_SET(parent_id, cid) > 0;     
						END WHILE;    
		ELSEIF tableName = 'sys_menu' THEN    
						WHILE cid is not null DO      
										SET str = concat(str, ',', cid);      
										SELECT group_concat(id) INTO cid FROM sys_menu where FIND_IN_SET(parent_id, cid) > 0;     
						END WHILE;    
		END IF;
		RETURN str;
		END
	 */
	@SuppressWarnings("unchecked")
	public List<T> findAllChilds(T entity,String func) {
		String entityname = getTableName(domainClass); 
		String id = null;
		if (entity != null){
			id = (String)Reflections.getFieldValue(entity, "id");
		}
		boolean flag=true;
		try {
			entity.getClass().getDeclaredField("delFlag");
		} catch (Exception e) {
			flag=false;
		}
		
		String sql="select * from "+entityname;
		if("getTableChilds".equals(func)){
			sql=sql+" where FIND_IN_SET(id,getTableChilds('"+entityname+"','"+id+"'))";
		}else{			
			sql=sql+" where FIND_IN_SET(id,"+func+"('"+id+"'))";
		}
		
		if (flag) {
			sql=sql+" and del_Flag = 0";
		}
		
		Query query=super.em.createNativeQuery(sql, entity.getClass());
		
		return query.getResultList();
	}

	/**
	 	BEGIN      
			DECLARE str varchar(1000);     
			DECLARE cid varchar(100); 
		     
			SET str = '$';      
			SET cid = rootId; 
		 
			IF tableName = 'sys_dict' THEN    
							WHILE cid is not null DO      
											SET str = concat(str, ',', cid);      
											SELECT group_concat(id) INTO cid FROM sys_dict where FIND_IN_SET(parent_id, cid) > 0;     
							END WHILE;    
			ELSEIF tableName = 'sys_menu' THEN    
							WHILE cid is not null DO      
											SET str = concat(str, ',', cid);      
											SELECT group_concat(id) INTO cid FROM sys_menu where FIND_IN_SET(parent_id, cid) > 0;     
							END WHILE;    
			END IF;
		
			RETURN str;
		END
	 
	 
	 */
	@SuppressWarnings("unchecked")
	public List<T> findAllParents(T entity, String func) {
		String entityname = getTableName(domainClass);
		String id = null;
		if (entity != null){
			id = (String)Reflections.getFieldValue(entity, "id");
		}
		
		String funcSQL="select ";
		if("getTableParents".equals(func)){
			funcSQL=funcSQL+"getTableParents('"+entityname+"','"+id+"')";
		}else{			
			funcSQL=funcSQL+func+"('"+id+"')";
		}
		Query funcQuery=super.em.createNativeQuery(funcSQL);
		
		String sql="select * from "+entityname+" where id in ("+funcQuery.getSingleResult().toString()+")";
		Query query=super.em.createNativeQuery(sql, entity.getClass());
		
		return query.getResultList();
	}

	
	
}